import { useCookie, navigateTo, useNuxtApp } from 'nuxt/app'
import { useUserStore } from '~/stores/user'
import { $fetch } from 'ofetch'

export const useApi = async <T>(url: string, options: any = {}): Promise<T> => {
  // 通过useNuxtApp获取上下文
  const nuxtApp = useNuxtApp()
  const userStore = useUserStore()
  const route = useRoute()
  
  // 获取accessToken和refreshToken
  const accessToken = useCookie('accessToken')
  const refreshToken = useCookie('refreshToken')
  
  // 添加一个标志来表示是否正在刷新token
  let isRefreshing = false
  // 存储等待刷新token的请求
  let refreshSubscribers: ((token: string) => void)[] = []
  
  // 刷新token的函数
  const refreshTokenFn = async () => {
    try {
      isRefreshing = true
      const response = await $fetch<{
        code: number;
        message: string;
        data: {
          accessToken: string;
          refreshToken: string;
        }
      }>('/api/refresh-token', {
        method: 'POST',
        credentials: 'include'
      })
      
      if (response.code !== 200) {
        throw new Error('刷新token失败')
      }
      
      const newTokens = response.data

      // 通知所有等待的请求
      refreshSubscribers.forEach(callback => callback(newTokens.accessToken))
      refreshSubscribers = []
      
      return newTokens.accessToken
    } catch (err) {
      console.log(err)
      // 刷新失败，清除token并跳转到登录页
      userStore.clearTokens()
      console.log(route.path)
      route.path==='/'? navigateTo('/') : navigateTo('/login')
      throw err
    } finally {
      isRefreshing = false
    }
  }
  
  try {
    // 请求前处理，如添加token
    if (accessToken.value) {
      options.headers = {
        ...options.headers,
        Authorization: `Bearer ${accessToken.value}`
      }
    }

    const data = await $fetch(url, {
      baseURL: '',
      ...options
    })
    return data as T
  } catch (error: any) {
    // 统一错误处理
    const status = error.status
    const statusText = error.statusText
    const originalRequest = {
      url,
      options
    }
    
    if (status === 401 && !originalRequest.url.includes('/api/refresh-token')) {
      if (!isRefreshing) {
        // 尝试刷新token
        try {
          const newAccessToken = await refreshTokenFn()
          
          // 用新token重试原始请求
          originalRequest.options.headers = {
            ...originalRequest.options.headers,
            Authorization: `Bearer ${newAccessToken}`
          }
          
          return $fetch<T>(originalRequest.url, originalRequest.options)
        } catch (err) {
          // 刷新失败，已经在refreshTokenFn函数中处理
          throw err
        }
      } else {
        // 如果正在刷新token，将请求添加到等待队列
        return new Promise((resolve) => {
          refreshSubscribers.push((token: string) => {
            originalRequest.options.headers = {
              ...originalRequest.options.headers,
              Authorization: `Bearer ${token}`
            }
            resolve($fetch<T>(originalRequest.url, originalRequest.options))
          })
        })
      }
    }
    
    // 处理其他错误
    switch (status) {
      case 403:
        // 通过nuxtApp上下文显示错误
        nuxtApp.callHook('app:error', '没有操作权限')
        break
      default:
        nuxtApp.callHook('app:error', `请求错误: ${statusText || '未知错误'}`)
    }
    
    throw error // 允许调用方捕获错误
  }
}
